import { Button, Form, FormInstance, Modal, Select } from "antd";
import { cloneDeep } from "lodash";
import { FC, HTMLAttributes, useContext, useRef } from "react";
import { ConfigurePageContext } from "../ConfigurePage";
import { ConfigType, ConfigurePageContentItemType } from "../ConfigurePageType";
import CatModule from "./components/CatModule";
import HorizontalGoodsModule from "./components/HorizontalGoodsModule";
import SwiperModule from "./components/SwiperModule";
import VerticalGoodsModule from "./components/VerticalGoodsModule";
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
import { hideScrollBar } from "@/components/styled";
import { StyledPreviewDevice, StyledNavBar, StyledCCD, StyledScreen } from "../ConfigurePage.styled";
import RichTextModule from "./components/RichTextModule";
import ModuleOperate from "./components/components/ModuleOperate";

export interface CommonModuleProps {
	className?: HTMLAttributes<HTMLDivElement>["className"];
	style?: HTMLAttributes<HTMLDivElement>["style"];
	onClick?: HTMLAttributes<HTMLDivElement>["onClick"];
	index: number;
}
const PreviewDevice = () => {
	const { content = [], addTypeOpen, setAddTypeOpen, setContent, operateIndex, selectedIndex, setSelectedIndex } = useContext(ConfigurePageContext);
	const moduleTypes: { key: string; name: ConfigType }[] = Object.entries(ConfigType).map(([key, name]) => ({ key, name }));
	const addTypeForm = useRef<FormInstance<{ type: ConfigurePageContentItemType }> | null>(null);
	const getModule = (Component: FC<CommonModuleProps>, index: number) => (
		<div
			className={`${index !== 0 ? "mt-2" : ""} relative bg-gray-100`}
			style={{ width: "calc(22vw - 16px)" }}
			onClick={() => setSelectedIndex(selectedIndex === index ? null : index)}
		>
			<ModuleOperate index={index}>{<Component index={index} />}</ModuleOperate>
		</div>
	);
	const moduleObject: Record<ConfigurePageContentItemType, FC<CommonModuleProps>> = {
		swiper: SwiperModule,
		cat: CatModule,
		verticalGoods: VerticalGoodsModule,
		horizontalGoods: HorizontalGoodsModule,
		richText: RichTextModule,
	};
	return (
		<StyledPreviewDevice className="bg-gray-200 shrink-0">
			<StyledNavBar>
				<StyledCCD />
			</StyledNavBar>
			<StyledScreen className={`overflow-y-scroll ${hideScrollBar}`}>
				<DragDropContext
					onDragEnd={({ source, destination }) => {
						if (!destination) return;
						const { index: sourceIndex } = source;
						const { index: destinationIndex } = destination;
						if (sourceIndex !== destinationIndex) {
							const sourceItem = cloneDeep(content[sourceIndex]);
							const destinationItem = cloneDeep(content[destinationIndex]);
							const copiedContent = cloneDeep(content);
							copiedContent[sourceIndex] = destinationItem;
							copiedContent[destinationIndex] = sourceItem;
							setContent(copiedContent);
							if (selectedIndex === destinationIndex) {
								setSelectedIndex(sourceIndex);
							}
							if (selectedIndex === sourceIndex) {
								setSelectedIndex(destinationIndex);
							}
						}
					}}
				>
					<Droppable droppableId="droppable_module">
						{dropProvided => (
							<div {...dropProvided.droppableProps} ref={dropProvided.innerRef}>
								{content.map(({ type }, index) => (
									<Draggable index={index} key={index} draggableId={`draggable_module_${index}`}>
										{dragProvided => (
											<div {...dragProvided.dragHandleProps} {...dragProvided.draggableProps} ref={dragProvided.innerRef}>
												{getModule(moduleObject[type], index)}
											</div>
										)}
									</Draggable>
								))}
								{dropProvided.placeholder}
							</div>
						)}
					</Droppable>
				</DragDropContext>

				<Button block className="m-2" style={{ width: "calc(22vw - 16px - 1rem)" }} onClick={() => setAddTypeOpen(true)}>
					添加模块
				</Button>
				{addTypeOpen && (
					<Modal
						open={addTypeOpen}
						title="添加模块类型"
						onCancel={() => setAddTypeOpen(false)}
						onOk={() => {
							const copiedData = cloneDeep(content);
							const type = addTypeForm.current?.getFieldValue("type");
							if (operateIndex === null) {
								copiedData.push({ type, status: true, list: [] });
							} else {
								copiedData.splice(operateIndex, 0, { type, status: true, list: [] });
							}
							setContent(copiedData);
							setAddTypeOpen(false);
						}}
					>
						<Form ref={addTypeForm} className="pt-3 pb-5" initialValues={{ type: "swiper" }}>
							<Form.Item name="type">
								<Select>
									{moduleTypes.map(item => (
										<Select.Option key={item.key}>{item.name}</Select.Option>
									))}
								</Select>
							</Form.Item>
						</Form>
					</Modal>
				)}
			</StyledScreen>
		</StyledPreviewDevice>
	);
};

export default PreviewDevice;
